#include "stdafx.h"
#include "fmtrec.h"

namespace xm
{
	#define REG_FORMAT(fmt)		{ FMT_##fmt, #fmt }
	
	FMTDESC gFormatTable [] = 
	{
		REG_FORMAT(PE),
		REG_FORMAT(SWX),
		REG_FORMAT(PDF),
		REG_FORMAT(DOC),
		REG_FORMAT(RTF),
		REG_FORMAT(DEX),
		REG_FORMAT(JCLS),
		REG_FORMAT(TIFF),
		REG_FORMAT(XDP),
	};
	
	struct DiscernItem
	{
		SIZE_T			MinLen;
		DiscernHandler	Handler;
	} 
	gDiscernTable [] = 
	{
		128,	DiscernWinPE		,
		0x100,	DiscernSWx		,
		0x200,	DiscernDOC		,
		0x100,	DiscernTIFF		,
		0x100,	DiscernPDF		,
		0x100,	DiscernDEX		,
		0x100,	DiscernELF		,
	};

	CONST SIZE_T DiscernCount = sizeof(gDiscernTable)/sizeof(gDiscernTable[0]);

	FMTDESC * WINAPI FormatGetByIndex( SIZE_T uIndex )
	{
		return NULL;
	}
	FMTDESC * WINAPI FormatQueryById( FileType TypeId )
	{
		return NULL;
	}
	FMTDESC * WINAPI XmFormatFromName( LPCSTR aName )
	{
		for( size_t i = 0; i < sizeof(gFormatTable)/sizeof(gFormatTable[0]); ++ i )
		{
			if( stricmp( gFormatTable[i].TypeName, aName ) )
				continue;
			return gFormatTable + i;
		}
		return NULL;
	}

	HRESULT	  WINAPI XmFormatDiscern( IKBStream * pstm, IKFormats * formats )
	{
		UTIL::sentry<UINT8*> buf = new UINT8[0x2000];
		if( !buf ) return E_OUTOFMEMORY;

		SIZE_T eff = 0;
		RFAILED( pstm->Readp( 0, buf, 0x2000, &eff ) );
		
		for( size_t i = 0; i < DiscernCount; ++ i )
		{
			if( eff < gDiscernTable[i].MinLen )
				continue;

			gDiscernTable[i].Handler( pstm, buf, eff, formats );
		}

		return S_OK;
	}

};